package com.hxzy.driver.service.impl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.hxzy.common.exception.HxdsException;
import com.hxzy.common.util.WeiXinAppUtil;
import com.hxzy.driver.entity.Driver;
import com.hxzy.driver.entity.DriverSettings;
import com.hxzy.driver.entity.Wallet;
import com.hxzy.driver.service.DriverService;
import com.hxzy.driver.mapper.DriverMapper;
import com.hxzy.driver.service.DriverSettingsService;
import com.hxzy.driver.service.WalletService;
import com.hxzy.drvier.req.RegisterNewDriverReq;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.iai.v20180301.IaiClient;
import com.tencentcloudapi.iai.v20180301.models.*;
import lombok.extern.log4j.Log4j2;
import org.eclipse.jetty.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
* @author 11452
* @description 针对表【tb_driver(代驾司机表)】的数据库操作Service实现
* @createDate 2023-12-13 16:32:27
*/
@Service
@Log4j2
public class DriverServiceImpl extends ServiceImpl<DriverMapper, Driver>
    implements DriverService{

    @Value("${tencent.cloud.secretId}")
    private String secretId;

    @Value("${tencent.cloud.secretKey}")
    private String secretKey;

    /**
     * 人脸识图片别库的名称
     */
    @Value("${tencent.face.groupName}")
    private String faceGroupName;

    /**
     * 人脸识别服务器位置
     */
    @Value("${tencent.face.region}")
    private String region;

    /**
     * 司机数据访问
     */
    @Autowired
    private DriverMapper driverMapper;

    /**
     * 司机接单规则设定
     */
    @Autowired
    private DriverSettingsService driverSettingsService;

    /**
     * 司机钱包
     */
    @Autowired
    private WalletService walletService;


    @Autowired
    private WeiXinAppUtil weiXinAppUtil;

    /**
     * LCN：@LcnTransaction    全自动的分布式事务的操作
     * TCC：@TccTransaction    手动的分布式事务的操作（写代码）
     * TXC：@TxcTransaction    自动，比较消息内存
     * 拿到微信小程序code（临时授权码，获取小程序openid），判断openid司机是否注册过
     * @param req
     * @return 主键键唯一值
     */
    @LcnTransaction
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String registerNewDriver(RegisterNewDriverReq req) {
        String code =  req.getCode();
        //获取小程序唯一的openid
        String openId = null;
        try {
            openId = this.weiXinAppUtil.getOpenId(code);
        } catch (JsonProcessingException e) {
            log.error(e);
            throw new HxdsException("该微信无法注册");
        }

        //查询司机表中openid是否>0
        long count=this.driverMapper.hasDriver(openId);
        if (count!=0) {
           //以前注册过了
            Driver dbDriver=this.driverMapper.getDriverByOpenId(openId);
            //资料还没有填完，重新换令牌
            if(dbDriver.getRealAuth()==1){
                String driverId=dbDriver.getId().toString();
                return driverId;
            }
            //有可能是审核中
            throw new HxdsException("该微信无法注册");
        }

        //初始化司机信息
        Driver  driver=new Driver();
        driver.setNickname(req.getNickname());
        driver.setPhoto(req.getPhoto());
        driver.setSex(req.getGender());
        driver.setOpenId(openId);
        //认证状态(身份证号码是否填写了，上传图片没有)
        driver.setRealAuth(1);
        //腾讯云人脸识别库是是否已经归档存放司机面部信息
        driver.setArchive(0);
        driver.setStatus(1);
        driver.setCreateTime(new Date());

        this.save(driver);


        //添加司机设置记录
        DriverSettings settingsEntity = new DriverSettings();
        settingsEntity.setDriverId(driver.getId());

        JSONObject json = new JSONObject();
        //定向接单
        json.set("orientation", "");
        //自动听单
        json.set("listenService", Boolean.TRUE);
        //代驾订单预估里程不限，司机不挑订单
        json.set("orderDistance", 0);
        //接收距离司机5公里以内的代驾单
        json.set("rangeDistance", 5);
        //自动抢单
        json.set("autoAccept", Boolean.FALSE);
        //转为json存储
        settingsEntity.setSettings(json.toString());

        this.driverSettingsService.save(settingsEntity);

        //添加司机钱包记录
        Wallet walletEntity = new Wallet();
        walletEntity.setDriverId(driver.getId());
        walletEntity.setBalance(new BigDecimal("0"));
        //支付密码为空，用户支付的时候，系统会自动提示用户设置支付密码
        walletEntity.setPassword(null);
        this.walletService.save(walletEntity);

        //得到数据库返回的自增长的id（因为仿止long数据太长，发给前端的时候，前端精度丢失的问题）
        return driver.getId().toString();

    }

    /**
     * 司机人脸识别图片归档
     * @param driverId
     * @param photo
     * @return
     */
    @LcnTransaction
    @Transactional
    @Override
    public String createDriverFaceModel(Long driverId, String photo) {
         //查询人员信息(name和sex)
        LambdaQueryWrapper<Driver> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Driver::getId,driverId);
        queryWrapper.select(Driver::getSex,Driver::getName);
        Driver dbDriver = this.getOne(queryWrapper);

        //创建腾讯云认证对象
        Credential cred = new Credential(secretId, secretKey);
        //腾讯云端创建司机面部档案
        IaiClient client = new IaiClient(cred, region);


        try{
            //检查上传的照片上面有没有人脸
            DetectFaceRequest detectFaceRequest = new DetectFaceRequest();
            detectFaceRequest.setMaxFaceNum(1L);
            detectFaceRequest.setMinFaceSize(34L);
            detectFaceRequest.setImage(photo);
            // 返回的resp是一个DetectFaceResponse的实例，与请求对象对应,如果有错误，会抛出异常TencentCloudSDKException
            client.DetectFace(detectFaceRequest);

            //创建人员档案请求
            CreatePersonRequest req = new CreatePersonRequest();
            //人员库ID
            req.setGroupId(this.faceGroupName);
            //人员ID
            req.setPersonId(driverId + "");
            long gender = dbDriver.getSex().equals("男") ? 1L : 2L;
            req.setGender(gender);
            //照片质量等级
            req.setQualityControl(4L);
            //重复人员识别等级
            req.setUniquePersonControl(4L);
            //姓名
            req.setPersonName(dbDriver.getName());
            //base64图片
            req.setImage(photo);

            //上传多张照片的请求 CreateFaceRequest createFaceRequest=new CreateFaceRequest();


            //向腾讯人脸识别人发送创建人员请求，并获取结果
            CreatePersonResponse resp = client.CreatePerson(req);

            //腾讯云创建人员成功
            if (StringUtil.isNotBlank(resp.getFaceId())) {
                //更新司机表的archive字段值
                Driver updateArchive=new Driver();
                updateArchive.setId(driverId);
                updateArchive.setArchive(1);
                boolean result = this.updateById(updateArchive);
                if (!result) {
                    return "更新司机归档字段失败";
                }
            }

        }catch (TencentCloudSDKException e) {
            log.error("创建腾讯云端司机档案失败", e);
            return e.getMessage();
        }

        return "";
    }

}




